package service

import (
	"fmt"
	"ginim/models"
	"ginim/utils"
	"github.com/asaskevich/govalidator"
	"github.com/gin-gonic/gin"
	"golang.org/x/exp/rand"
	"net/http"
	"strconv"
	"text/template"
)

// GetUserList
// @Tags 用户
// @Summary 获取用户列表
// @Success 200 {string} json{"code","message"}
// @Router /user/list [get]
func GetUserList(ctx *gin.Context) {

	data := make([]*models.User, 10)
	data = models.GetUserList()

	ctx.JSON(http.StatusOK, gin.H{
		"message": data,
	})
}

func LoginPage(ctx *gin.Context) {
	idx, err := template.ParseFiles("templates/views/login.html")
	if err != nil {
		panic(err)
	}
	idx.Execute(ctx.Writer, "home")
}

func RegisterPage(ctx *gin.Context) {
	idx, err := template.ParseFiles("web/views/user/register.html")
	if err != nil {
		panic(err)
	}
	idx.Execute(ctx.Writer, "home")
}

// FindUserByNameAndPassword
// @Tags 用户
// @Summary 验证用户名和密码
// @Param name formData string false "用户名"
// @Param password formData string false "密码"
// @Success 200 {string} json{"code","message","user"}
// @Router /user/check [post]
func FindUserByNameAndPassword(ctx *gin.Context) {
	user := models.User{}
	user.Name = ctx.PostForm("name")
	user.Password = ctx.PostForm("password")
	dbUser := models.FindUserByName(user.Name)
	if dbUser.Name == "" {
		ctx.JSON(http.StatusBadRequest, gin.H{
			"message": fmt.Sprintf("用户名: %s 不存在.", user.Name),
			"user":    user,
			"code":    -1,
		})
		return
	}

	isOk := utils.DecryptionPassword(user.Password, dbUser.Salt, dbUser.Password)
	if !isOk {
		ctx.JSON(http.StatusOK, gin.H{
			"message": "密码错误",
			"user":    user,
			"code":    -1,
		})
		return
	}

	dbUser = models.FindUserByNameAndPassword(user.Name, dbUser.Password)
	if dbUser.Name == "" {
		ctx.JSON(http.StatusBadRequest, gin.H{
			"message": fmt.Sprintf("用户名: %s 不存在.", user.Name),
			"user":    user,
			"code":    -1,
		})
		return
	}

	models.UpdateUserIdentity(dbUser.ID)
	ctx.JSON(http.StatusOK, gin.H{
		"message": "登录成功",
		"user":    dbUser,
		"code":    0,
	})
}

// CreateUser
// @Tags 用户
// @Summary 创建用户
// @Param name formData string false "用户名"
// @Param password formData string false "密码"
// @Param email formData string false "邮箱"
// @Param phone formData string false "手机号"
// @Success 200 {string} json{"code","message","user"}
// @Router /user/add [post]
func CreateUser(ctx *gin.Context) {
	user := models.User{}
	user.Name = ctx.PostForm("name")
	user.Password = ctx.PostForm("password")
	user.Phone = ctx.PostForm("phone")
	user.Email = ctx.PostForm("email")
	salt := fmt.Sprintf("%06d", rand.Int31())

	dbUser := models.FindUserByName(user.Name)
	if dbUser.Name != "" {
		ctx.JSON(http.StatusOK, gin.H{
			"message": fmt.Sprintf("user name: %s already in use.", user.Name),
			"user":    user,
			"code":    0,
		})
		return
	}

	dbUser = models.FindUserByEmail(user.Email)
	if dbUser.Email != "" {
		ctx.JSON(http.StatusOK, gin.H{
			"message": fmt.Sprintf("user eamil: %s already in use.", user.Email),
			"user":    user,
			"code":    0,
		})
		return
	}

	dbUser = models.FindUserByPhone(user.Phone)
	if dbUser.Phone != "" {
		ctx.JSON(http.StatusOK, gin.H{
			"message": fmt.Sprintf("user phone: %s already in use.", user.Phone),
			"user":    user,
			"code":    0,
		})
		return
	}

	user.Password = utils.EncryptionPassword(user.Password, salt)
	user.Salt = salt
	models.CreateUser(user)
	ctx.JSON(http.StatusOK, gin.H{
		"message": "add user success",
		"user":    user,
		"code":    0,
	})
}

func FindUserById(c *gin.Context) {
	userId, _ := strconv.Atoi(c.Request.FormValue("userId"))

	//	name := c.Request.FormValue("name")
	data := models.FindUserById(uint(userId))
	utils.ResponseSuccess(c.Writer, data, "ok")
}

// DeleteUser
// @Tags 用户
// @Summary 删除用户
// @Param id query string false "用户ID"
// @Success 200 {string} json{"code","message"}
// @Router /user/delete [delete]
func DeleteUser(ctx *gin.Context) {

	user := models.User{}
	id, _ := strconv.Atoi(ctx.Query("id"))
	user.ID = uint(id)

	models.DeleteUser(user)

	ctx.JSON(http.StatusOK, gin.H{
		"message": "delete user success",
	})
}

// UpdateUser
// @Tags 用户
// @Summary 更新用户
// @Param id formData string false "用户ID"
// @Param name formData string false "用户名称"
// @Param password formData string false "用户密码"
// @Param phone formData string false "手机号"
// @Param email formData string false "邮箱"
// @Success 200 {string} json{"code","message"}
// @Router /user/update [put]
func UpdateUser(ctx *gin.Context) {

	user := models.User{}
	id, _ := strconv.Atoi(ctx.PostForm("id"))
	user.ID = uint(id)

	user.Name = ctx.PostForm("name")
	user.Password = ctx.PostForm("password")
	user.Phone = ctx.PostForm("phone")
	user.Email = ctx.PostForm("email")
	user.Avatar = ctx.PostForm("avatar")

	// 校验
	_, err := govalidator.ValidateStruct(user)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{
			"message": fmt.Sprintf("update failure, %s", err),
		})
		return
	}

	models.UpdateUser(user)
	ctx.JSON(http.StatusOK, gin.H{
		"message": "更新成功",
	})
}

func SendUserMsg(ctx *gin.Context) {
	models.Chat(ctx.Writer, ctx.Request)
}

func RedisMsg(c *gin.Context) {
	userIdA, _ := strconv.Atoi(c.PostForm("userIdA"))
	userIdB, _ := strconv.Atoi(c.PostForm("userIdB"))
	start, _ := strconv.Atoi(c.PostForm("start"))
	end, _ := strconv.Atoi(c.PostForm("end"))
	isRev, _ := strconv.ParseBool(c.PostForm("isRev"))
	res := models.RedisMsg(int64(userIdA), int64(userIdB), int64(start), int64(end), isRev)
	utils.ResponseListData(c.Writer, "ok", res)
}

func FindFriends(ctx *gin.Context) {
	userId, _ := strconv.Atoi(ctx.PostForm("userId"))
	users := models.FindFriends(uint(userId))
	utils.ResponseListData(ctx.Writer, users, len(users))
}

func AddFriend(ctx *gin.Context) {
	username := ctx.PostForm("username")
	userId, _ := strconv.Atoi(ctx.PostForm("userId"))
	code, msg := models.AddFriend(uint(userId), username)
	if code == 1 {
		utils.ResponseSuccess(ctx.Writer, code, msg)
	} else {
		utils.ResponseFailure(ctx.Writer, msg)
	}
}
